#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# this lesson is based on python 3

import re # regular expression module

re.match(r'23\d', '239') # \d for single number
# return a Match object if matched, return None if not matched
r'12\w' == '12a' # \w for single number or letter
r'py.' == 'py!' # . for any single character
# 用*表示任意个字符（包括0个），
# 用+表示至少一个字符，
# 用?表示0个或1个字符，
# 用{n}表示n个字符，
# 用{n,m}表示n-m个字符：

# 来看一个复杂的例子：
r'\d{3}\s+\d{3,8}'

# 我们来从左到右解读一下：

# d{3}表示匹配3个数字，例如'010'；
# \s可以匹配一个空格（也包括Tab等空白符），所以\s+表示至少有一个空格，例如匹配' '等；
# \d{3,8}表示3-8个数字，例如'1234567'。

'''
要做更精确地匹配，可以用[]表示范围，比如：

    [0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线；
    [0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串，比如'a100'，'0_Z'，'Py3000'等等；
    [a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头，后接任意个由一个数字、字母或者下划线组成的字符串，
        ---也就是Python合法的变量；
    [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精确地限制了变量的长度是1-20个字符（前面1个字符+后面最多19个字符）。

A|B可以匹配A或B，所以(P|p)ython可以匹配'Python'或者'python'。
^表示行的开头，^\d表示必须以数字开头。
$表示行的结束，\d$表示必须以数字结束。

你可能注意到了，py也可以匹配'python'，但是加上^py$就变成了整行匹配，就只能匹配'py'了。
'''
# re.split can split by continued space
re.split(r'\s+', 'a b   c') # ['a', 'b', 'c']
# include comma
re.split(r'[\s\,]+', 'a,b, c  d') # ['a', 'b', 'c', 'd']
# include semicolon
re.split(r'[\s\,\;]+', 'a,b;; c  d') # ['a', 'b', 'c', 'd']

m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
m.group(0) # '010-12345' original string
m.group(1) # '010'
m.group(2) # '12345'

# 正则匹配默认是贪婪匹配，也就是匹配尽可能多的字符
re.match(r'^(\d+)(0*)$', '102300').groups() # ('102300', '')
# 采用非贪婪匹配（也就是尽可能少匹配），加个?就可以
re.match(r'^(\d+?)(0*)$', '102300').groups() # ('1023', '00')

# 如果一个正则表达式要重复使用几千次，出于效率的考虑，我们可以预编译该正则表达式
re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')
re_telephone.match('010-12345').groups() # ('010', '12345')